package com.wahoyu.exportwordtest.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.deepoove.poi.data.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

/**
 * 运行报告导出-业务实现
 * @Author wanghongyu02
 * @Date 2025/4/21 16:51
 */
@Service
@Slf4j
public class ReportService {

    @Autowired
    private HttpRequestService httpRequestService;
    @Autowired
    private EchartsService echartsService;

    // 图片的长宽，在js中也对其进行了配置
    private static final int IMG_WIDTH = 550;
    private static final int IMG_HIGH = 322;

    /**
     * （总方法）将数据填充到报表中
     * @param wordConfigMap
     * @author wanghongyu02
     * @Date 2025/4/22 09:26
     */
    public void getReportData(Map<String, Object> wordConfigMap, String customerId) {

        // 定义请求参数map
        Map<String, String> reqMap = new HashMap<>();
        if (StringUtils.isNotEmpty(customerId)) {
            reqMap.put("customerId", customerId);
        }

        // 0.0 设置年月
        this.setYearAndMonth(wordConfigMap);

        // 1.2 网络开通使用情况
        this.setNetProductsList(wordConfigMap, reqMap);

        // 1.3 网络设备使用情况
        this.setNetDeviceInfo(wordConfigMap, reqMap);

        // 2.1 设置客户申告表格（倒数时间表格）
        this.setCustomerReportTable(wordConfigMap, reqMap);

        // 2.1 设置故障清单表格 + 2.1 故障申告数量
        this.setFaultListTable(wordConfigMap, reqMap);

        // 2.3 主动监控表格
        this.setActiveListTable(wordConfigMap, reqMap);

        // 3.1 设置互联网专线数据
        this.setNetLineInfo(wordConfigMap, reqMap);

        // 3.2 设置MPLS-VPN数据
        this.setMPLSVPNInfo(wordConfigMap, reqMap);

        // 3.3 设置以太网专线数据
        this.setELineInfo(wordConfigMap, reqMap);

        // 4.1 设置客户机房巡检情况
        this.setInspectTable(wordConfigMap, reqMap);

        // 4.2 其他网络服务
        this.setOtherServiceInfo(wordConfigMap, reqMap);

    }

    /**
     * 设置年月
     * @param map
     * @author wanghongyu02
     * @Date 2025/4/22 09:27
     */
    private void setYearAndMonth(Map<String, Object> map) {

        // 当前时间
        LocalDate currentDate = LocalDate.now();
        map.put("year", String.valueOf(currentDate.getYear()));
        map.put("month", String.valueOf(currentDate.getMonthValue()));

        // 上个月时间
        LocalDate previousMonthDate = currentDate.minusMonths(1);
        map.put("previousYear", String.valueOf(previousMonthDate.getYear()));
        map.put("previousMonth", String.valueOf(previousMonthDate.getMonthValue()));
    }


    /**
     * 1.2 网络开通使用情况
     * @param map
     * @author wanghongyu02
     * @Date 2025/4/22 11:00
     */
    private void setNetProductsList(Map<String, Object> map, Map<String, String> reqMap) {
        reqMap.put("reportId", "04aafd7cccd282ca442163d4056a52f6");
        List<JSONObject> resultList = httpRequestService.getDataByFeign(reqMap, "1.2网络开通使用情况");
        map.put("netProductsList", resultList);
    }


    /**
     * 1.3 网络设备使用情况
     * @param map
     * @author wanghongyu02
     * @Date 2025/4/22 11:00
     */
    private void setNetDeviceInfo(Map<String, Object> map, Map<String, String> reqMap) {

        // 1.3数量
        reqMap.put("reportId", "9054d9f4f2ed53f20fef20ae46a95e18");
        List<JSONObject> resultNetDeviceNum = httpRequestService.getDataByFeign(reqMap, "1.3 网络设备使用情况");
        map.put("netDeviceNum", resultNetDeviceNum.get(0).getString("netDeviceNum"));

        // 1.3表格
        reqMap.put("reportId", "488de8c19f63a63533e2082dbea94180");
        List<JSONObject> resultList = httpRequestService.getDataByFeign(reqMap, "1.3 网络设备使用情况");
        // 循环给列表设置id
        for (int i = 0; i < resultList.size(); i++) {
            resultList.get(i).put("id", i + 1);
        }
        map.put("netDeviceList", resultList);
    }


    /**
     * 2.1 设置客户申告表格（倒数时间表格）
     * @param map
     * @author wanghongyu02
     * @Date 2025/4/22 11:00
     */
    private void setCustomerReportTable(Map<String, Object> map, Map<String, String> reqMap) {

        reqMap.put("reportId", "105a360072e4dd1a92cb106eabe2aa53");
        List<JSONObject> resultList = httpRequestService.getDataByFeign(reqMap, "2.1 设置客户申告表格");

        // 从第一个非零count开始展示
        for (int i = resultList.size()-1; i >= 0; i--) {
            if (!"0".equals(resultList.get(i).getString("count"))) {
                break;
            }
            resultList.remove(i);
        }

        if (CollectionUtils.isEmpty(resultList)) {
            resultList.add(new JSONObject().fluentPut("month", " ").fluentPut("count", " "));
        }

        map.put("customerReportTable", resultList);
    }

    /**
     * 2.1 故障申告数量
     * 2.1 设置故障清单表格
     * @param map
     * @author wanghongyu02
     * @Date 2025/4/22 11:00
     */
    private void setFaultListTable(Map<String, Object> map, Map<String, String> reqMap) {

        // 2.1 故障申告数量
        reqMap.put("reportId", "ac4a91c146c8ee531aa59f8449403a1d");
        List<JSONObject> numList = httpRequestService.getDataByFeign(reqMap, "2.1 故障申告数量");
        if (CollectionUtils.isNotEmpty(numList)) {
            map.put("faultNum", numList.get(0).getString("faultNum"));
        }

        // 2.1 设置故障清单表格
        reqMap.put("reportId", "3137cb1db904cf3abf8b543214eff9c0");
        List<JSONObject> resultList = httpRequestService.getDataByFeign(reqMap, "2.1 设置故障清单表格");
        // 循环给列表设置id
        for (int i = 0; i < resultList.size(); i++) {
            resultList.get(i).put("id", i + 1);
        }
        map.put("faultList", resultList);
    }


    /**
     * 2.3 设置主动监控表格
     * @param map
     * @author wanghongyu02
     * @Date 2025/4/22 11:00
     */
    private void setActiveListTable(Map<String, Object> map, Map<String, String> reqMap) {
        reqMap.put("reportId", "1ac7367343d9add918767e1a021c5cc4");
        List<JSONObject> resultList = httpRequestService.getDataByFeign(reqMap, "2.3 设置主动监控表格");

        // 循环给列表设置id
        for (int i = 0; i < resultList.size(); i++) {
            resultList.get(i).put("id", i + 1);
        }
        map.put("activeList", resultList);
    }


    /**
     * 3.1 设置互联网专线数据
     * @param map
     * @author wanghongyu02
     * @Date 2025/4/22 11:00
     */
    private void setNetLineInfo(Map<String, Object> map, Map<String, String> reqMap) {

        // 1. 查询表格
        reqMap.put("reportId", "2c07b9488e1fe36f29b504edfe08a248");
        List<JSONObject> resultList = httpRequestService.getDataByFeign(reqMap, "3.1 设置互联网专线数据");
        // 循环给列表设置id
        for (int i = 0; i < resultList.size(); i++) {
            resultList.get(i).put("id", i + 1);
        }
        map.put("netLineTable", resultList);

        // 2. 查询总数
        reqMap.put("reportId", "2c07b9488e1fe36f29b504edfe08a250");
        List<JSONObject> countList = httpRequestService.getDataByFeign(reqMap, "3.1 设置互联网专线数据");
        int count = 0;
        if (CollectionUtils.isNotEmpty(countList) && countList.get(0).containsKey("count")) {
            count = countList.get(0).getInteger("count");
        }
        map.put("netLineNum", count);

        // 3. 图片操作

        // 查询打标号码
        reqMap.put("reportId", "2c07b9488e1fe36f29b504edfe08a249");
        List<JSONObject> numberList = httpRequestService.getDataByFeign(reqMap, "3.1 设置互联网专线数据");
        log.info("打标号码合集：{}", numberList); // 540HLW055728

        // 初始化组合模板items
        List<Map<String, Object>> items = new ArrayList<>();

        // 如果没有业务号码不展示数据
        if (CollectionUtils.isEmpty(numberList)) {
            items.add(new HashMap<String, Object>() {{
                put("text_31", "当前无重要电路流量。");
            }});
        } else {
            for (int i = 0; i < numberList.size(); i++) {
                HashMap<String, Object> itemMap = new HashMap<>();
                itemMap.put("text_31", "（" + (i+1) + "）、" + numberList.get(i).getString("a_business_number"));

                // 拿到图片的bytes数组
                byte[] imgBytes = this.getBytesByNumber(numberList.get(i).getString("a_business_number"), "2c07b9488e1fe36f29b504edfe08a251");
                itemMap.put("image_31",  Pictures.ofBytes(imgBytes).size(IMG_WIDTH, IMG_HIGH).create());
                items.add(itemMap);
            }
        }
        map.put("items_31", items);
    }


    /**
     * 3.2 设置MPLS-VPN数据
     * @param map
     * @author wanghongyu02
     * @Date 2025/4/22 11:00
     */
    private void setMPLSVPNInfo(Map<String, Object> map, Map<String, String> reqMap) {

        // 1. 查询表格
        reqMap.put("reportId", "2c7721ac7037d06ab44ecba5a7ce84d7");
        List<JSONObject> resultList = httpRequestService.getDataByFeign(reqMap, "3.2 设置MPLS-VPN数据");
        // 循环给列表设置id
        for (int i = 0; i < resultList.size(); i++) {
            resultList.get(i).put("id", i + 1);
        }
        map.put("mplsTable", resultList);

        // 2. 查询总数
        reqMap.put("reportId", "2c7721ac7037d06ab44ecba5a7ce84d8");
        List<JSONObject> countList = httpRequestService.getDataByFeign(reqMap, "3.2 设置MPLS-VPN数据");
        int count = 0;
        if (CollectionUtils.isNotEmpty(countList) && countList.get(0).containsKey("count")) {
            count = countList.get(0).getInteger("count");
        }
        map.put("mplsVpnNum", count);

        // 3. 图片操作

        // 查询打标号码
        reqMap.put("reportId", "2c07b9488e1fe36f29b504edfe08a249");
        List<JSONObject> numberList = httpRequestService.getDataByFeign(reqMap, "3.2 设置MPLS-VPN数据");
        log.info("打标号码合集：{}", numberList); // 540HLW055728

        // 初始化组合模板items
        List<Map<String, Object>> items = new ArrayList<>();

        // 如果没有业务号码不展示数据
        if (CollectionUtils.isEmpty(numberList)) {
            items.add(new HashMap<String, Object>() {{
                put("text_32", "当前无重要电路流量。");
            }});
        } else {
            for (int i = 0; i < numberList.size(); i++) {
                HashMap<String, Object> itemMap = new HashMap<>();
                itemMap.put("text_32", "（" + (i+1) + "）、" + numberList.get(i).getString("a_business_number"));

                // 拿到图片的bytes数组
                byte[] imgBytes = this.getBytesByNumber(numberList.get(i).getString("a_business_number"), "2c07b9488e1fe36f29b504edfe08a251");
                itemMap.put("image_32",  Pictures.ofBytes(imgBytes).size(IMG_WIDTH, IMG_HIGH).create());
                items.add(itemMap);
            }
        }
        map.put("items_32", items);

    }


    /**
     * 3.3 设置以太网专线数据
     * @param map
     * @author wanghongyu02
     * @Date 2025/4/22 11:00
     */
    private void setELineInfo(Map<String, Object> map, Map<String, String> reqMap) {

        // 1. 查询表格
        reqMap.put("reportId", "9fad9fd3fa04f25a79a2d0737ff9064d");
        List<JSONObject> resultList = httpRequestService.getDataByFeign(reqMap, "3.3 设置以太网专线数据");
        // 循环给列表设置id
        for (int i = 0; i < resultList.size(); i++) {
            resultList.get(i).put("id", i + 1);
        }
        map.put("eLineTable", resultList);

        // 2. 查询总数
        reqMap.put("reportId", "9fad9fd3fa04f25a79a2d0737ff9064f");
        List<JSONObject> countList = httpRequestService.getDataByFeign(reqMap, "3.3 设置以太网专线数据");
        int count = 0;
        if (CollectionUtils.isNotEmpty(countList) && countList.get(0).containsKey("count")) {
            count = countList.get(0).getInteger("count");
        }
        map.put("eLineNum", count);

        // 3. 图片操作

        // 查询打标号码
        reqMap.put("reportId", "9fad9fd3fa04f25a79a2d0737ff9064e");
        List<JSONObject> numberList = httpRequestService.getDataByFeign(reqMap, "3.3 设置以太网专线数据");
        log.info("打标号码合集：{}", numberList); // 540HLW055728

        // 初始化组合模板items
        List<Map<String, Object>> items = new ArrayList<>();

        // 如果没有业务号码不展示数据
        if (CollectionUtils.isEmpty(numberList)) {
            items.add(new HashMap<String, Object>() {{
                put("text_33", "当前无重要电路流量。");
            }});
        } else {
            for (int i = 0; i < numberList.size(); i++) {
                HashMap<String, Object> itemMap = new HashMap<>();
                itemMap.put("text_33", "（" + (i+1) + "）、" + numberList.get(i).getString("a_business_number"));

                // 拿到图片的bytes数组
                byte[] imgBytes = this.getBytesByNumber(numberList.get(i).getString("a_business_number"), "2c7721ac7037d06ab44ecbb5a7ce84e1");
                itemMap.put("image_33",  Pictures.ofBytes(imgBytes).size(IMG_WIDTH, IMG_HIGH).create());
                items.add(itemMap);
            }
        }
        map.put("items_33", items);
    }


    /**
     * 4.1 设置客户机房巡检情况
     * @param map
     * @author wanghongyu02
     * @Date 2025/4/22 11:00
     */
    private void setInspectTable(Map<String, Object> map, Map<String, String> reqMap) {

        reqMap.put("reportId", "bbee121df468232c3f3b0789c3bfb262");
        List<JSONObject> resultList = httpRequestService.getDataByFeign(reqMap, "4.1设置客户机房巡检情况");
        if (CollectionUtils.isNotEmpty(resultList) && resultList.get(0).containsKey("customerName")) {
            RowRenderData row0 = Rows.of("客户名称", "项目名称", "巡检时间", "巡检人员" , "巡检结果").center().create();
            TableRenderData tableRenderData = Tables.create(row0);
            for (JSONObject item : resultList) {
                String[] valueList = new String[5];
                valueList[0] = item.getString("customerName");
                valueList[1] = item.getString("projectName");
                valueList[2] = item.getString("inspectTime");
                valueList[3] = item.getString("inspectPerson");
                valueList[4] = item.getString("inspectResult");
                tableRenderData.addRow(Rows.of(valueList).center().create());
            }
            map.put("inspectTable", tableRenderData);
        } else {
            map.put("inspectTableMsg", "本月未安排巡检");
        }
    }

    /**
     * 4.2 其他网络服务
     * @param map
     * @author wanghongyu02
     * @Date 2025/4/22 11:00
     */
    private void setOtherServiceInfo(Map<String, Object> map, Map<String, String> reqMap) {

        reqMap.put("reportId", "724cdc4663a954f4265e6c08853baf61");
        List<JSONObject> resultList = httpRequestService.getDataByFeign(reqMap, "4.1设置客户机房巡检情况");
        if (!resultList.isEmpty()) {
            JSONObject item = resultList.get(0);
            map.put("netManagerName",item.getString("netManagerName"));
            map.put("netManagerTel",item.getString("netManagerTel"));
            map.put("customerManagerName",item.getString("customerManagerName"));
            map.put("customerManagerTel",item.getString("customerManagerTel"));
        }
    }

    /**
     * 传出number，拿到图片的byte数组
     * @param aBusinessNumber
     * @param sqlId visual_report_config表中对应的主键
     * @return
     * @author wanghongyu02
     * @Date 2025/4/27 09:40
     */
    private byte[] getBytesByNumber(String aBusinessNumber, String sqlId) {

        // 获取上个月的月初和月末时间
        LocalDateTime now = LocalDateTime.now().minusMonths(1);
        LocalDateTime firstDayOfMonth = now.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
        LocalDateTime lastDayOfMonth = now.with(TemporalAdjusters.lastDayOfMonth())
                .withHour(23).withMinute(59).withSecond(59);

        // 格式化时间参数（根据数据库实际格式调整）
        DateTimeFormatter dbFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String startTime = firstDayOfMonth.format(dbFormatter);
        String endTime = lastDayOfMonth.format(dbFormatter);

        // 构建查询参数
        Map<String, String> params = new HashMap<>();
        params.put("reportId", sqlId);
        params.put("aBusinessNumber", aBusinessNumber);
        params.put("startTime", startTime);
        params.put("endTime", endTime);

        // 执行SQL查询（假设有数据库工具类执行查询）
        List<JSONObject> resultList = httpRequestService.getDataByFeign(params, "3.1&3.2 折线图数据查询");
        // 按时间排序（如果SQL未排序）
        resultList.sort(Comparator.comparing(
                m -> LocalDateTime.parse((String) m.get("dTime")))
        );

        // 初始化三个存储数组的集合
        List<String> dTimeList = new ArrayList<>();
        List<Double> outFlowList = new ArrayList<>();
        List<Double> inFlowList = new ArrayList<>();
        for (JSONObject item : resultList) {
            dTimeList.add(item.getString("dTime"));
            outFlowList.add(item.getDouble("outFlow"));
            inFlowList.add(item.getDouble("inFlow"));
        }
        HashMap<String, Object> templateMap = new HashMap<>();
        templateMap.put("dTimeList", JSON.toJSONString(dTimeList));
        templateMap.put("outFlowList", JSON.toJSONString(outFlowList));
        templateMap.put("inFlowList", JSON.toJSONString(inFlowList));
        log.info("折线图数据：{}", templateMap);

        byte[] imgByteData;
        try {
            imgByteData = echartsService.getEchartsImgBytes(templateMap, "reportOption.txt");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return imgByteData;
    }



}